﻿using UnityEngine;
using System;

namespace Mars.DeviceProfiles
{
    public class IOSDeviceProfileSelector : IDeviceProfileSelector
    {
        // 配置文件相关
        private const string fileName = "IOSCommonDeviceProfileConfig"; // json格式的存储配置文件名

        private FIOSCommonDeviceProfileConfig config; // 解析后的json数据

        // 设备相关的信息
        private string GPUFamily;
        private string GLVersion;
        private string DeviceModel;
        private string DeviceMake;
        private string OSVersion;
        private string MemorySizeInGB;
        private string CPUNumCores;
        private string CPUMaxFreq;
        private string VulkanAvailable; // 这三个参数暂时用不上
        private string VulkanVersion;
        private string UsingHoudini;

        public string GetGPUFamily()
        {
            return GPUFamily;
        }

        public string GetGLVersion()
        {
            return GLVersion;
        }

        public string GetDeviceModel()
        {
            return DeviceModel;
        }

        public string GetDeviceMake()
        {
            return DeviceMake;
        }

        public string GetOSVersion()
        {
            return OSVersion;
        }

        public string GetMemorySizeInGB()
        {
            return MemorySizeInGB;
        }

        public string GetCPUNumCores()
        {
            return CPUNumCores;
        }

        public string GetCPUMaxFreq()
        {
            return CPUMaxFreq;
        }

        //ios没有评分，都是根据设置直接指定
        public int GetScore()
        {
            return 0;
        }

        // 计算后的配置文件名 用于区分每一个细分类型
        public string Profile = "";
        ETCQualityGrade QualityGrade = ETCQualityGrade.Grade01;

        void InitDeviceInfo()
        {
            GPUFamily = SystemInfo.graphicsDeviceName;
            Debug.Log("GPUFamily: " + GPUFamily);
            GLVersion = SystemInfo.graphicsDeviceVersion;
            Debug.Log("GLVersion: " + GLVersion);
            DeviceModel = SystemInfo.deviceModel;
            Debug.Log("DeviceModel: " + DeviceModel);
            DeviceMake = "Apple";
            Debug.Log("DeviceMake: " + DeviceMake);
            OSVersion = SystemInfo.operatingSystem;
            Debug.Log("IOSVersion: " + OSVersion);
            // 内存换成GB单位，并且上取整数
            int GBData = SystemInfo.systemMemorySize % 1024 == 0
                ? SystemInfo.systemMemorySize / 1024
                : SystemInfo.systemMemorySize / 1024 + 1;
            MemorySizeInGB = GBData.ToString();
            Debug.Log("MemorySizeInGB: " + MemorySizeInGB);
            CPUNumCores = SystemInfo.processorCount.ToString();
            Debug.Log("CPUNumCores: " + CPUNumCores);
            CPUMaxFreq = SystemInfo.processorFrequency.ToString();
            Debug.Log("CPUMaxFreq: " + CPUMaxFreq);
            // 这三个参数暂时没法获取
            VulkanAvailable = "";
            VulkanVersion = "";
            UsingHoudini = "";
        }

        private void LoadJsonFromFile()
        {
            TextAsset file = Resources.Load(fileName) as TextAsset;
            if (file != null)
            {
                string dataAsJson = file.ToString();
                config = JsonUtility.FromJson<FIOSCommonDeviceProfileConfig>(dataAsJson);
                Debug.Log("IOSCommonDeviceProfile config Data loaded!");
            }
            else
            {
                Debug.LogError(
                    "Cannot find IOSCommonDeviceProfile.json! Make sure file in \"Assets/StreamingAssets\" path. And file suffix should be \".json \"");
            }
        }

#if UNITY_IOS
    #region C code

    [DllImport("__Internal")]
    // return DeviceIDSring iPhone10,4
    private static extern string _getDeviceIDString();
    #endregion
#endif
        string GetDeviceIDString()
        {
            string retStr = DeviceModel;
#if UNITY_EDITOR
            retStr = DeviceModel;
#elif UNITY_IOS
        retStr = _getDeviceIDString();
#else
        retStr = DeviceModel;
#endif
            return retStr;
        }

        void GetIOSDeviceType()
        {
            // if we've already figured it out, return it
            if (Profile != string.Empty)
            {
                return;
            }

            string DeviceIDString = GetDeviceIDString();
            if (DeviceIDString == null)
            {
                return;
            }

            for (int i = 0; i < config.GradeMatchProfileWhiteList.Length; i++)
            {
                FIOSProfileMatch profile = config.GradeMatchProfileWhiteList[i];
                int CommaIndex = -1;
                int Major = 0;
                int Minor = 0;
                if (DeviceIDString.StartsWith(profile.Match.StartWith))
                {
                    CommaIndex = DeviceIDString.IndexOf(",");
                    Major = 0;
                    Minor = 0;
                    if (CommaIndex >= 0) // 如果有逗号
                    {
                        for (int j = profile.Match.StartWith.Length; j < CommaIndex; j++)
                        {
                            if (DeviceIDString[j] >= '0' && DeviceIDString[j] <= '9')
                            {
                                Major = Major * 10 + (DeviceIDString[j] - '0');
                            }
                            else
                            {
                                break;
                            }
                        }

                        for (int j = CommaIndex + 1; j < DeviceIDString.Length; j++)
                        {
                            if (DeviceIDString[j] >= '0' && DeviceIDString[j] <= '9')
                            {
                                Minor = Minor * 10 + (DeviceIDString[j] - '0');
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    if (Major >= int.Parse(profile.Match.MajorBegin) && Major <= int.Parse(profile.Match.MajorEnd)
                                                                     && Minor >= int.Parse(profile.Match.MinorBegin) &&
                                                                     Minor <= int.Parse(profile.Match.MinorEnd))
                    {
                        Profile = profile.Profile;
                        if (Enum.IsDefined(typeof(ETCQualityGrade), profile.TCQualityGrade))
                        {
                            QualityGrade = (ETCQualityGrade)Enum.Parse(typeof(ETCQualityGrade), profile.TCQualityGrade);
                        }
                        else
                        {
                            Debug.LogError("ETCQualityGrade config error : " + profile.TCQualityGrade);
                        }

                        break;
                    }
                }
            }

            // if this is unknown at this point, we have a problem
            if (Profile == string.Empty)
            {
                Debug.LogError("This IOS device type is not supported by IOSDeviceProfile :" + DeviceIDString);
            }
            else
            {
                Debug.Log(DeviceIDString + " -> " + Profile + " " + QualityGrade.ToString());
            }
        }

        public void InitData()
        {
            LoadJsonFromFile();
            InitDeviceInfo();
        }

        public string FindMatchingProfile()
        {
            GetIOSDeviceType();
            return Profile;
        }

        // 获取当前设备等级 1 2 3是低配 4 5是中配 6 7是高配
        public ETCQualityGrade GetDeviceGrade()
        {
            GetIOSDeviceType();
            return QualityGrade;
        }

        // 是否在黑名单里面
        public bool IsInBlackList()
        {
            GetIOSDeviceType();
            for (int i = 0; i < config.GradeMatchProfileBlackList.Length; i++)
            {
                if (Profile != string.Empty && Profile == config.GradeMatchProfileBlackList[i])
                {
                    return true;
                }
            }

            return false;
        }
    }
}